package com.ceam.biz.activiti.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ceam.biz.activiti.consts.ActivitiConstant;
import com.ceam.biz.activiti.entity.BizBusiness;
import com.ceam.biz.activiti.mapper.BizBusinessMapper;
import com.ceam.biz.activiti.service.BizNodeService;
import com.ceam.biz.activiti.service.IBizBusinessService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author CeaM
 * @Description
 * @date 2020/11/26 10:22
 */
@Service
public class BizBusinessServiceImpl extends ServiceImpl<BizBusinessMapper, BizBusiness> implements IBizBusinessService{

    @Autowired
    private BizBusinessMapper businessMapper;

    @Autowired
    private RuntimeService    runtimeService;

    @Autowired
    private IdentityService   identityService;

    @Autowired
    private TaskService       taskService;

    @Autowired
    private BizNodeService bizNodeService;

    @Override
    public BizBusiness selectBizBusinessById(String id) {
        return baseMapper.selectById(id);
    }

    @Override
    public List<BizBusiness> selectBizBusinessList(BizBusiness bizBusiness) {
        return baseMapper.selectList(new QueryWrapper<BizBusiness>());
    }

    @Override
    public int insertBizBusiness(BizBusiness bizBusiness) {
        return baseMapper.insert(bizBusiness);
    }

    @Override
    public int updateBizBusiness(BizBusiness bizBusiness) {
        return baseMapper.updateById(bizBusiness);
    }

    @Override
    public int deleteBizBusinessByIds(String ids) {
        return baseMapper.deleteById(ids);
    }

    @Override
    public int deleteBizBusinessLogic(String ids) {
        return baseMapper.deleteById(ids);
    }

    @Override
    public int deleteBizBusinessById(Long id) {
        return baseMapper.deleteById(id);
    }

    @Override
    public void startProcess(BizBusiness business, Map<String, Object> variables)
    {

        // 启动流程用户
        identityService.setAuthenticatedUserId(business.getUserId().toString());
        // 启动流程 需传入业务表id变量
        ProcessInstance pi = runtimeService.startProcessInstanceById(business.getProcDefId(),
                business.getId().toString(), variables);
        BizBusiness bizBusiness = new BizBusiness().setId(business.getId()).setProcInstId(pi.getId())
                .setProcDefKey(pi.getProcessDefinitionKey());
        // 假如开始就没有任务，那就认为是中止的流程，通常是不存在的
        setAuditor(bizBusiness, ActivitiConstant.RESULT_SUSPEND, business.getUserId());
    }

    @Override
    public int setAuditor(BizBusiness business, int result, long currentUserId)
    {
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(business.getProcInstId()).list();
        if (tasks != null && tasks.size() > 0)
        {
            Task task = tasks.get(0);
            Set<String> auditors = bizNodeService.getAuditors(task.getTaskDefinitionKey(), currentUserId);
            if (auditors != null && auditors.size() > 0)
            {
                for (String auditor : auditors)
                {
                    taskService.addCandidateUser(task.getId(), auditor);
                }
                business.setCurrentTask(task.getName());
            }
            else
            {
                runtimeService.deleteProcessInstance(task.getProcessInstanceId(),
                        ActivitiConstant.SUSPEND_PRE + "no auditor");
                business.setCurrentTask(ActivitiConstant.END_TASK_NAME).setStatus(ActivitiConstant.STATUS_SUSPEND)
                        .setResult(ActivitiConstant.RESULT_SUSPEND);
            }
        }
        else
        {
            // 任务结束
            business.setCurrentTask(ActivitiConstant.END_TASK_NAME).setStatus(ActivitiConstant.STATUS_FINISH)
                    .setResult(result);
        }
        return updateBizBusiness(business);
    }
}
